package com.rtx.edi.platform.handler;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.rtx.edi.model.api.po.PlApiMappingStructure;
import com.rtx.edi.platform.jobextend.bean.dto.JobConfigDTO;
import com.rtx.edi.platform.jobextend.bean.po.PlJobMapping;
import com.rtx.edi.platform.jobextend.service.ApiJobService;
import com.rtx.edi.platform.jobextend.service.PlJobMappingService;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

/**
 * APIJOB处理
 */
@Component
public class ApiJobHandler {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ApiJobService apiJobService;

    @Autowired
    private PlJobMappingService plJobMappingService;

    /**
     * 处理APIJOB
     * @param jobName
     */
    public void handler(String jobName){
        logger.info("api——job开始----------------------------");
        try {
            //获取配置信息
            JobConfigDTO jobConfig = apiJobService.selectConfig(jobName);
            logger.info("获取到配置：{}",JSONUtil.toJsonStr(jobConfig));
            for(String whseid : Arrays.asList("wmwhse1")){
                //获取数据
                Map<String, List<Map<String, Object>>> dataMap = plJobMappingService.executeSqlByJobId(whseid, jobConfig.getPlJob().getId());
                logger.info("获取到数据：{}",JSONUtil.toJsonStr(dataMap));
                if(CollectionUtils.isEmpty(dataMap)){
                    return;
                }
                if("0".equals(jobConfig.getPlJob().getJobType())){
                    //发送数据定时任务
                    sendDataJob(whseid,jobConfig,dataMap);
                }else{
                    //中间处理定时任务
                    handlerDataJob(whseid,jobConfig,dataMap);
                }
            }
        } catch (Exception e) {
            logger.error("任务名：{}，处理异常",jobName,e);
        }
        logger.info("api——job结束***************************");
    }

    /**
     * 处理数据定时任务
     * @param whseid
     * @param jobConfig
     * @param dataMap
     */
    private void handlerDataJob(String whseid, JobConfigDTO jobConfig, Map<String, List<Map<String, Object>>> dataMap) {
        List<Map<String, Object>> mainData = dataMap.get("mainData");
        if(CollectionUtils.isEmpty(mainData)){
            return;
        }
        //todo 暂不处理
    }

    /**
     * 发送数据定时任务
     * @param whseid
     * @param jobConfig
     * @param dataMap
     */
    private void sendDataJob(String whseid, JobConfigDTO jobConfig, Map<String, List<Map<String, Object>>> dataMap) {
        //获取主数据
        List<Map<String, Object>> mainData = dataMap.get("mainData");
        if(CollectionUtils.isEmpty(mainData)){
            return;
        }
        if("array".equals(jobConfig.getPlJob().getRequestDateType())){
            //发送请求
            String result  = send(jobConfig,mainData);
            //处理结果
            handlerResult(whseid,jobConfig,result);
        }else {
            for(Map<String, Object> data : mainData){
                //发送请求
                String result = send(jobConfig,data);
                //处理结果
                handlerResult(whseid,jobConfig,data,result);
            }
        }
    }
    /**
     * 发送请求
     * @param jobConfig
     * @param data
     * @return
     */
    private String send(JobConfigDTO jobConfig,Object data) {
        //转化数据
        String body = convertData(jobConfig,JSONUtil.toJsonStr(data));
        logger.info("发送请求地址：{}，数据：{}",jobConfig.getUrl(),body);
        String result = HttpRequest
                .post(jobConfig.getUrl())
                .body(body)
                .timeout(30000)
                .execute()
                .body();
        logger.info("发送请求地址：{}，结果：{}",jobConfig.getUrl(),result);
        return result;
    }

    /**
     * 处理结果(结果返回Array)
     * @param jobConfig
     * @param result
     */
    private void handlerResult(String whseid,JobConfigDTO jobConfig, String result) {
        //转化结果
        JSONArray resultArray = JSONUtil.parseArray(result);
        //更新结果语句   update orders set ediflag =#{status} where orderkey =#{orderkey}
        String updateSql = jobConfig.getPlJob().getUpdateSql();
        logger.info("替换前的SQL：{}",updateSql);
        //占位符 [{"placeholder":"#{orderkey}","source":"request","sourcepath":"mainData数组.出库单单号"},{"placeholder":"#{status} ","source":"response","sourcepath":"code"},{"placeholder":"#{msg} ","source":"response","sourcepath":"message"}]
        String updateColumn = jobConfig.getPlJob().getUpdColumn();
        for(int i = 0; i < resultArray.size(); i++){
            //替换占位符
            updateSql = replaceUpdateSql(updateSql,null,resultArray.getJSONObject(i),updateColumn);
            logger.info("替换后的SQL：{}",updateSql);
            apiJobService.executeSql(whseid,updateSql);
        }
    }

    /**
     * 替换SQL占位符
     * @param sql
     * @param data
     * @param result
     * @param updateColumn
     * @return
     */
    private String replaceUpdateSql(String sql, Map<String, Object> data, JSONObject result, String updateColumn){
        JSONArray columns = JSONUtil.parseArray(updateColumn);
        for(int i = 0; i < columns.size(); i ++){
            JSONObject column = columns.getJSONObject(i);
            if("request".equals(column.getStr("source"))){
                if(data != null){
                    sql = sql.replace(column.getStr("placeholder"),"'" + data.get(column.getStr("sourcepath")) + "'");
                }
            }else{
                Object value = JSONUtil.getByPath(result,column.getStr("sourcepath"));
                sql = sql.replace(column.getStr("placeholder"),"'" + value + "'");
            }
        }
        return sql;
    }

    /**
     * 处理结果(结果返回Object)
     * @param jobConfig
     * @param data
     * @param result
     */
    private void handlerResult(String whseid,JobConfigDTO jobConfig, Map<String, Object> data, String result) {
        //更新结果语句   update orders set ediflag =#{status} where orderkey =#{orderkey}
        String updateSql = jobConfig.getPlJob().getUpdateSql();
        logger.info("替换前的SQL：{}",updateSql);
        //占位符       [{"placeholder":"orderkey","column":"出库单单号"}]
        String updateColumn = jobConfig.getPlJob().getUpdColumn();
        updateSql = replaceUpdateSql(updateSql,data,JSONUtil.parseObj(result),updateColumn);
        logger.info("替换后的SQL：{}",updateSql);
        apiJobService.executeSql(whseid,updateSql);
    }

    /**
     * 转化数据
     * @param jobConfig
     * @param data
     * @return
     */
    private String convertData(JobConfigDTO jobConfig, String data) {
        if(jobConfig.getPlJobMappings() == null){
            return data;
        }
        //目标模板
        String targetJson = jobConfig.getApiInfo().getApiRequestTemplate();
        //字段对应结构
        List<PlApiMappingStructure> structureList = getstructureList(jobConfig);
        //转化报文结构
        JsonConvert convert = new JsonConvert(data,targetJson,structureList,null);
        convert.convert();
        return convert.getTargetJosn();
    }

    /**
     * 获取字段对应结构
     * @param jobConfig
     * @return
     */
    private List<PlApiMappingStructure> getstructureList(JobConfigDTO jobConfig) {
        List<PlApiMappingStructure> structureList = null;
        List<PlJobMapping> plJobMappings = jobConfig.getPlJobMappings();
        if(!CollectionUtils.isEmpty(plJobMappings)){
            structureList = new ArrayList<>();
            for(PlJobMapping m : plJobMappings){
                PlApiMappingStructure s = new PlApiMappingStructure();
                BeanUtils.copyProperties(m,s);
                structureList.add(s);
            }
        }
        return structureList;
    }

}
